/*!
 * \file WtLocalExecuter.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief 本地执行器头文件
 * 
 * 本文件定义了本地执行器相关的类和接口，主要包括：
 * - ExeUnitWrapper: 执行单元包装器，管理执行单元的生命周期
 * - WtExecuterFactory: 执行器工厂，负责创建和管理执行单元
 * - WtLocalExecuter: 本地执行器，实现具体的交易执行逻辑
 * 
 * 本地执行器是WonderTrader系统中的核心执行组件，负责将策略信号
 * 转换为具体的交易指令，并管理订单的执行过程。
 */
#pragma once
#include <boost/core/noncopyable.hpp>

#include "ITrdNotifySink.h"
#include "IExecCommand.h"
#include "../Includes/ExecuteDefs.h"

#include "../Share/DLLHelper.hpp"
#include "../Share/threadpool.hpp"

NS_WTP_BEGIN
class WTSVariant;
class IDataManager;
class TraderAdapter;
class IHotMgr;

//////////////////////////////////////////////////////////////////////////
/**
 * @class ExeUnitWrapper
 * @brief 执行单元包装器类
 * 
 * 执行单元包装器用于管理执行单元的生命周期，主要功能包括：
 * 1. 执行单元的安全创建和销毁
 * 2. 防止直接delete导致的内存问题
 * 3. 通过工厂实例的deleteUnit方法安全释放执行单元
 * 
 * 由于执行单元在dll中创建，如果没有包装器的话，直接delete可能会出现问题，
 * 因此需要将工厂指针一起包装进来，直接调用工厂实例的deleteUnit方法释放执行单元。
 */
class ExeUnitWrapper
{
public:
	/**
	 * @brief 构造函数
	 * @param unitPtr 执行单元指针
	 * @param fact 执行器工厂指针
	 * 
	 * 初始化执行单元包装器，保存执行单元和工厂的引用
	 */
	ExeUnitWrapper(ExecuteUnit* unitPtr, IExecuterFact* fact):_unit(unitPtr),_fact(fact){}
	
	/**
	 * @brief 析构函数
	 * 
	 * 通过工厂实例安全释放执行单元
	 */
	~ExeUnitWrapper()
	{
		if(_unit)
		{
			_fact->deleteExeUnit(_unit);
		}
	}

	/**
	 * @brief 获取执行单元指针
	 * @return 执行单元指针
	 */
	ExecuteUnit* self(){ return _unit; }


private:
	ExecuteUnit*	_unit;		///< 执行单元指针
	IExecuterFact*	_fact;		///< 执行器工厂指针
};

typedef std::shared_ptr<ExeUnitWrapper>	ExecuteUnitPtr;

//////////////////////////////////////////////////////////////////////////
/**
 * @class WtExecuterFactory
 * @brief 执行器工厂类
 * 
 * 执行器工厂负责管理和创建执行单元，主要功能包括：
 * 1. 动态加载执行器工厂模块
 * 2. 创建指定类型的执行单元
 * 3. 管理工厂实例的生命周期
 * 4. 提供统一的执行单元创建接口
 */
class WtExecuterFactory : private boost::noncopyable
{
public:
	~WtExecuterFactory() {}

public:
	/**
	 * @brief 加载执行器工厂
	 * @param path 工厂模块路径
	 * @return 是否加载成功
	 * 
	 * 从指定路径加载执行器工厂模块，初始化工厂实例
	 */
	bool loadFactories(const char* path);

	/**
	 * @brief 创建执行单元
	 * @param name 执行单元名称
	 * @return 执行单元智能指针
	 * 
	 * 根据名称创建执行单元，自动查找对应的工厂
	 */
	ExecuteUnitPtr createExeUnit(const char* name);
	
	/**
	 * @brief 创建执行单元
	 * @param factname 工厂名称
	 * @param unitname 执行单元名称
	 * @return 执行单元智能指针
	 * 
	 * 根据工厂名称和执行单元名称创建执行单元
	 */
	ExecuteUnitPtr createExeUnit(const char* factname, const char* unitname);

private:
	/**
	 * @brief 执行器工厂信息结构体
	 * 
	 * 存储执行器工厂的相关信息，包括模块路径、实例、创建和删除函数等
	 */
	typedef struct _ExeFactInfo
	{
		std::string		_module_path;	///< 模块路径
		DllHandle		_module_inst;	///< 模块句柄
		IExecuterFact*	_fact;			///< 工厂实例
		FuncCreateExeFact	_creator;	///< 创建函数
		FuncDeleteExeFact	_remover;	///< 删除函数
	} ExeFactInfo;
	typedef faster_hashmap<LongKey, ExeFactInfo> ExeFactMap;

	ExeFactMap	_factories;				///< 工厂映射表
};

/**
 * @class WtLocalExecuter
 * @brief 本地执行器类
 * 
 * 本地执行器是WonderTrader系统中的核心执行组件，主要功能包括：
 * 1. 执行单元管理：创建、管理和调度执行单元
 * 2. 交易执行：处理买卖指令，管理订单状态
 * 3. 持仓管理：跟踪和更新持仓信息
 * 4. 数据服务：提供行情数据、合约信息等服务
 * 5. 事件处理：处理交易事件、行情事件等
 * 6. 风险控制：执行风险控制策略
 * 7. 多线程支持：使用线程池处理并发任务
 * 
 * 该类继承自ExecuteContext、ITrdNotifySink和IExecCommand，
 * 实现了完整的执行器功能接口。
 */
class WtLocalExecuter : public ExecuteContext,
		public ITrdNotifySink, public IExecCommand
{
public:
	typedef faster_hashmap<LongKey, ExecuteUnitPtr> ExecuteUnitMap;

public:
	/**
	 * @brief 构造函数
	 * @param factory 执行器工厂指针
	 * @param name 执行器名称
	 * @param dataMgr 数据管理器指针
	 * 
	 * 初始化本地执行器，设置工厂、名称和数据管理器
	 */
	WtLocalExecuter(WtExecuterFactory* factory, const char* name, IDataManager* dataMgr);
	
	/**
	 * @brief 析构函数
	 * 
	 * 清理资源，释放执行单元
	 */
	virtual ~WtLocalExecuter();

public:
	/**
	 * @brief 初始化执行器
	 * @param params 初始化参数
	 * @return 是否初始化成功
	 * 
	 * 根据配置参数初始化执行器，包括缩放比例、自动清理等设置
	 */
	bool init(WTSVariant* params);

	/**
	 * @brief 设置交易适配器
	 * @param adapter 交易适配器指针
	 * 
	 * 设置执行器使用的交易适配器
	 */
	inline void setTrader(TraderAdapter* adapter)
	{
		_trader = adapter;
	}

private:
	/**
	 * @brief 获取执行单元
	 * @param code 合约代码
	 * @param bAutoCreate 是否自动创建
	 * @return 执行单元智能指针
	 * 
	 * 根据合约代码获取对应的执行单元，如果不存在且允许自动创建则创建新的执行单元
	 */
	ExecuteUnitPtr	getUnit(const char* code, bool bAutoCreate = true);

public:
	//////////////////////////////////////////////////////////////////////////
	// ExecuteContext接口实现
	
	/**
	 * @brief 获取Tick数据切片
	 * @param code 合约代码
	 * @param count 数据数量
	 * @param etime 结束时间，默认为0
	 * @return Tick数据切片
	 */
	virtual WTSTickSlice* getTicks(const char* code, uint32_t count, uint64_t etime = 0) override;

	/**
	 * @brief 获取最新Tick数据
	 * @param code 合约代码
	 * @return 最新Tick数据
	 */
	virtual WTSTickData*	grabLastTick(const char* code) override;

	/**
	 * @brief 获取持仓数量
	 * @param stdCode 标准合约代码
	 * @param validOnly 是否只返回有效持仓
	 * @param flag 持仓标志，默认为3（多空都包含）
	 * @return 持仓数量
	 */
	virtual double		getPosition(const char* stdCode, bool validOnly = true, int32_t flag = 3) override;
	
	/**
	 * @brief 获取订单映射表
	 * @param code 合约代码
	 * @return 订单映射表指针
	 */
	virtual OrderMap*	getOrders(const char* code) override;
	
	/**
	 * @brief 获取未完成数量
	 * @param code 合约代码
	 * @return 未完成数量
	 */
	virtual double		getUndoneQty(const char* code) override;

	/**
	 * @brief 买入操作
	 * @param code 合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param bForceClose 是否强制平仓
	 * @return 订单ID列表
	 */
	virtual OrderIDs	buy(const char* code, double price, double qty, bool bForceClose = false) override;
	
	/**
	 * @brief 卖出操作
	 * @param code 合约代码
	 * @param price 价格
	 * @param qty 数量
	 * @param bForceClose 是否强制平仓
	 * @return 订单ID列表
	 */
	virtual OrderIDs	sell(const char* code, double price, double qty, bool bForceClose = false) override;
	
	/**
	 * @brief 撤销订单
	 * @param localid 本地订单ID
	 * @return 是否撤销成功
	 */
	virtual bool		cancel(uint32_t localid) override;
	
	/**
	 * @brief 撤销订单
	 * @param code 合约代码
	 * @param isBuy 是否为买单
	 * @param qty 撤销数量
	 * @return 订单ID列表
	 */
	virtual OrderIDs	cancel(const char* code, bool isBuy, double qty) override;
	
	/**
	 * @brief 写入日志
	 * @param message 日志消息
	 */
	virtual void		writeLog(const char* message) override;

	/**
	 * @brief 获取品种信息
	 * @param stdCode 标准合约代码
	 * @return 品种信息
	 */
	virtual WTSCommodityInfo*	getCommodityInfo(const char* stdCode) override;
	
	/**
	 * @brief 获取交易时段信息
	 * @param stdCode 标准合约代码
	 * @return 交易时段信息
	 */
	virtual WTSSessionInfo*		getSessionInfo(const char* stdCode) override;

	/**
	 * @brief 获取当前时间
	 * @return 当前时间戳
	 */
	virtual uint64_t	getCurTime() override;

public:
	/**
	 * @brief 设置目标持仓
	 * @param targets 目标持仓映射表
	 * 
	 * 设置各个合约的目标持仓，执行器会根据目标持仓进行交易
	 */
	virtual void set_position(const faster_hashmap<LongKey, double>& targets) override;

	/**
	 * @brief 合约持仓变动回调
	 * @param stdCode 标准合约代码
	 * @param targetPos 目标持仓
	 * 
	 * 当某个合约的目标持仓发生变化时的回调函数
	 */
	virtual void on_position_changed(const char* stdCode, double targetPos) override;

	/**
	 * @brief 实时行情回调
	 * @param stdCode 标准合约代码
	 * @param newTick 新的Tick数据
	 * 
	 * 接收实时行情数据的回调函数
	 */
	virtual void on_tick(const char* stdCode, WTSTickData* newTick) override;

	/**
	 * @brief 成交回报回调
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param isBuy 是否为买单
	 * @param vol 成交数量
	 * @param price 成交价格
	 * 
	 * 接收成交回报的回调函数
	 */
	virtual void on_trade(uint32_t localid, const char* stdCode, bool isBuy, double vol, double price) override;

	/**
	 * @brief 订单回报回调
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param isBuy 是否为买单
	 * @param totalQty 总数量
	 * @param leftQty 剩余数量
	 * @param price 价格
	 * @param isCanceled 是否已撤销
	 * 
	 * 接收订单回报的回调函数
	 */
	virtual void on_order(uint32_t localid, const char* stdCode, bool isBuy, double totalQty, double leftQty, double price, bool isCanceled = false) override;

	/**
	 * @brief 持仓回报回调
	 * @param stdCode 标准合约代码
	 * @param isLong 是否为多头
	 * @param prevol 昨仓数量
	 * @param preavail 昨仓可用
	 * @param newvol 今仓数量
	 * @param newavail 今仓可用
	 * @param tradingday 交易日
	 *	
	 * 接收持仓回报的回调函数
	 */
	virtual void on_position(const char* stdCode, bool isLong, double prevol, double preavail, double newvol, double newavail, uint32_t tradingday) override;

	/**
	 * @brief 委托回报回调
	 * @param localid 本地订单ID
	 * @param stdCode 标准合约代码
	 * @param bSuccess 是否成功
	 * @param message 消息内容
	 *	
	 * 接收委托回报的回调函数
	 */
	virtual void on_entrust(uint32_t localid, const char* stdCode, bool bSuccess, const char* message) override;

	/**
	 * @brief 交易通道就绪回调
	 * 
	 * 当交易通道连接成功并就绪时的回调函数
	 */
	virtual void on_channel_ready() override;

	/**
	 * @brief 交易通道断开回调
	 * 
	 * 当交易通道连接断开时的回调函数
	 */
	virtual void on_channel_lost() override;


private:
	ExecuteUnitMap		_unit_map;		///< 执行单元映射表
	TraderAdapter*		_trader;		///< 交易适配器
	WtExecuterFactory*	_factory;		///< 执行器工厂
	IDataManager*		_data_mgr;		///< 数据管理器
	WTSVariant*			_config;		///< 配置信息

	double				_scale;			///< 放大倍数
	bool				_auto_clear;	///< 是否自动清理（清理上一个交易日的持仓）
	bool				_channel_ready;	///< 通道是否就绪

	faster_hashset<LongKey>	_clear_includes;	///< 自动清理包含品种集
	faster_hashset<LongKey>	_clear_excludes;	///< 自动清理排除品种集

	faster_hashmap<LongKey, double> _target_pos;	///< 目标持仓映射表

	typedef std::shared_ptr<boost::threadpool::pool> ThreadPoolPtr;
	ThreadPoolPtr		_pool;			///< 线程池
};

typedef std::shared_ptr<IExecCommand> ExecCmdPtr;
typedef std::shared_ptr<WtLocalExecuter> WtExecuterPtr;

NS_WTP_END
